package com.hzqy.commons.utils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class XiRuanUtil {
	private static final Log LOG = LogFactory.getLog(XiRuanUtil.class);
	
	public static String xr_url = "";
	public static String appkey = "";
	public static String secret = "";
	public static String xr_hotelid = "";
	public static String hotelid = "";
	public static final String LOGIN_MENTHOD = "xmsopen.public.login";
	public static final String LOGINOUT_MENTHOD = "xmsopen.public.logout";
	public static final String GETMESSAGE_MENTHOD = "xmsopen.room.xopgetroomliveininfo";
	public static String sign = "";
	public static final String LOCAL = "zh_CN";
	public static String ver = "";
	public static String session="";
	
	static{
		xr_url = SystemConfigUtils.getSysConfig("xr_url");
		xr_hotelid = SystemConfigUtils.getSysConfig("xr_hotelid");
		ver = SystemConfigUtils.getSysConfig("xr_ver");
	}
	
	public static String login(String hotel){
		appkey = SystemConfigUtils.getSysConfig(hotel+"_appkey");
		hotelid = SystemConfigUtils.getSysConfig(hotel+"_hotelid");
		secret = SystemConfigUtils.getSysConfig(hotel+"_secret");
		
		LOG.debug("appkey:"+appkey);
		LOG.debug("hotelid:"+hotelid);
		LOG.debug("secret:"+secret);
		
		String signText = "";
		long t = System.currentTimeMillis();
		signText += appkey + xr_hotelid + LOCAL + t;
		
		/*HashMap<String,Object> signParamsMap = new HashMap<String,Object>();
		JSONObject obj= JSON.parseObject(signParamsMap.toString());
		String strBizText = createRequestSign(obj,secret);
		signText += strBizText;*/
		
		signText += secret;
		sign = MD5Util.MD5_32bit(signText);
		
		JSONObject jj = new JSONObject();
		jj.put("appkey", appkey);
		jj.put("secret", secret);
		jj.put("method", LOGIN_MENTHOD);
		jj.put("ver", ver);
		jj.put("hotelid", xr_hotelid);
		jj.put("loc", LOCAL);
		jj.put("ts", t);
		jj.put("sign", sign);
		
		String result = post(xr_url,jj.toString());
		LOG.debug("result:"+result);
		JSONObject resultJson = JSONObject.parseObject(result);
		if((boolean) resultJson.get("success")){
			session = String.valueOf(resultJson.get("session"));
			LOG.debug("登录成功，session："+session);
			
		}else{
			LOG.debug("登录失败，获取session失败。");
		}
		return session;
	}
	
	public static void loginOut(String hotel,String session){
		appkey = SystemConfigUtils.getSysConfig(hotel+"_appkey");
		hotelid = SystemConfigUtils.getSysConfig(hotel+"_hotelid");
		secret = SystemConfigUtils.getSysConfig(hotel+"_secret");
		
		String signText = "";
		long t = System.currentTimeMillis();
		signText += appkey + xr_hotelid + LOCAL + t;
		
		/*HashMap<String,Object> signParamsMap = new HashMap<String,Object>();
		JSONObject obj= JSON.parseObject(signParamsMap.toString());
		String strBizText = createRequestSign(obj,secret);
		signText += strBizText;*/
		
		signText += secret;
		sign = MD5Util.MD5_32bit(signText);
		
		JSONObject jj = new JSONObject();
		jj.put("appkey", appkey);
		jj.put("session", session);
		jj.put("method", LOGINOUT_MENTHOD);
		jj.put("ver", ver);
		jj.put("hotelid", xr_hotelid);
		jj.put("loc", LOCAL);
		jj.put("ts", t);
		jj.put("sign", sign);
		
		String result = post(xr_url,jj.toString());
		//LOG.debug("result:"+result);
		JSONObject resultJson = JSONObject.parseObject(result);
		if((boolean) resultJson.get("success")){
			LOG.debug("登出成功");
		}else{
			LOG.debug("登出失败");
		}
	}
	
	public static String getMessage(String hotel,String roomno){
		String str = "";
		appkey = SystemConfigUtils.getSysConfig(hotel+"_appkey");
		hotelid = SystemConfigUtils.getSysConfig(hotel+"_hotelid");
		secret = SystemConfigUtils.getSysConfig(hotel+"_secret");
		
		String signText = "";
		long t = System.currentTimeMillis();
		signText += appkey + xr_hotelid + LOCAL + t;
		
		JSONObject obj = new JSONObject();
		obj.put("roomno", roomno);
		obj.put("hotelid", hotelid);
		
		String strBizText = createRequestSign(obj,secret);
		signText += strBizText;
		
		signText += secret;
		sign = MD5Util.MD5_32bit(signText);
		
		List<JSONObject> list = new ArrayList<JSONObject>();
		list.add(obj);
		JSONObject jj = new JSONObject();
		jj.put("appkey", appkey);
		jj.put("session", session);
		jj.put("method", GETMESSAGE_MENTHOD);
		jj.put("ver", ver);
		jj.put("hotelid", xr_hotelid);
		jj.put("loc", LOCAL);
		jj.put("ts", t);
		jj.put("sign", sign);
		jj.put("params", list);
		
		String result = post(xr_url,jj.toString());
		LOG.debug("result:"+result);
		JSONObject resultJson = JSONObject.parseObject(result);
		if((boolean) resultJson.get("success")){
			LOG.debug("获取房间号："+roomno+"数据成功。"+resultJson.get("results"));
			try {
				JSONArray ja = JSONArray.parseArray(resultJson.get("results").toString());
				for(int i=0;i<ja.size();i++){
					JSONObject message = JSONObject.parseObject(ja.get(i).toString());
					String name = String.valueOf(message.get("name"));
					String sex = String.valueOf(message.get("sex"));
					str += name;
					if("0".equals(sex)){
						str += "先生";
					}else if("1".equals(sex)){
						str += "女士";
					}
					if(i<ja.size()-1){
						str += ",";
					}
				}
			} catch (Exception e) {
				str = "客人";
				//LOG.error("数据解析失败。"+e.getMessage());
			}
		}else{
			LOG.debug(resultJson.get("msg"));
			if("request.session is invalid".equals(resultJson.get("msg"))||"xmsopen.exception.request.session.invalid".equals(resultJson.get("code"))){
				LOG.debug("session无效 重新发起请求。");
				login(hotel);
				str = "again";
			}
		}
		return str;
	}
	
	public static String createRequestSign(JSONObject request,String secret){
		/**
		* 创建数字校验
		* 1.预先json序列化
		* 2.遍历获取所有非空params
		* 3.排序数组
		* 4.组合数据，然后md5
		*/
		String md5 = null;
		try {
			List<String> values = new ArrayList<String>();
			JSONArray params = request.getJSONArray("params");
			walkRequest(params, values);
			Collections.sort(values);
			String signStr = "";
			signStr += request.getString("appkey") + request.getString("hotelid");
			signStr += request.getString("loc") + request.getLong("ts");
			for (int i = 0; i < values.size(); i++) {
				signStr += values.get(i);
			}
			signStr += secret;
			
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(signStr.getBytes());
			StringBuffer sb = new StringBuffer();
			for (byte b : md.digest()) {
				sb.append(String.format("%02X", b));
			}
			md5 = sb.toString();
		} catch (Exception e) {
			//LOG.error("西软login失败："+e.getMessage());
		}
		
		return md5;
	}
	
	/**
	* 获取JSONObject中所有不为空的值
	*
	* @param obj
	* @param values
	*/
	private static void walkRequest(Object obj, List<String> values) {
		if (obj instanceof JSONObject) {
			JSONObject jso = (JSONObject) obj;
			for (String key : jso.keySet()) {
				walkRequest(jso.get(key), values);
			}
		} else if (obj instanceof JSONArray) {
			JSONArray ary = (JSONArray) obj;
			for (int i = 0; i < ary.size(); i++) {
				walkRequest(ary.get(i), values);
			}
		} else if (obj != null) {
			if (obj instanceof Date) {
				values.add(String.valueOf(((Date) obj).getTime()).toUpperCase());
			} else {
				values.add(obj.toString().toUpperCase());
			}
		}
	}
	
	public static String sendPost(String urlStr,int readTimeOut,int connectTimeout) {
		HttpURLConnection con = null;
		Map<String, String> map = new HashMap<String, String>();
		String result = "";
		InputStream is = null;
		InputStreamReader isr = null;
		BufferedReader br =null;
		try {// 获取HttpURLConnection连接对象
			URL url = new URL(urlStr);
			con = (HttpURLConnection) url.openConnection();
			// 设置连接属性
			con.setDoOutput(true);  
            con.setRequestMethod("POST");
            con.setRequestProperty("version", "1.0");  
            con.setRequestProperty("Content-Type", "text/json");  
            con.setRequestProperty("Pragma", "no-cache");  
            con.setRequestProperty("Cache-Control", "no-cache");
            con.setConnectTimeout(connectTimeout);
            con.setReadTimeout(readTimeOut);

			int respCode = con.getResponseCode();
			if (respCode == 200) {
				is = con.getInputStream();
				isr = new InputStreamReader(is,"UTF-8");
				br = new BufferedReader(isr);
				//BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
	            String line = "";  
	            for (line = br.readLine(); line != null; line = br.readLine()) { 
	            	result+=line;
	            }
			}
		} catch (Exception e) {
			e.printStackTrace();
			LOG.error("请求失败",e);
			
		}finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
				}
			}
			if (isr != null) {
				try {
					isr.close();
				} catch (IOException e) {
				}
			}
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
				}
			}
			if(con != null)
				con.disconnect();
		}
		
		return result;
	}
	
	public static String post(String url,String json) {
		String result= "";
		try {
		HttpClient client = HttpClientBuilder.create().build();
		HttpPost httpPost = new HttpPost(url);
		httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
		
		StringEntity se;
		se = new StringEntity(json);
		se.setContentType("text/json");
		se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
		httpPost.setEntity(se);
		HttpResponse response=client.execute(httpPost);
		result=EntityUtils.toString(response.getEntity());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

}
